    function based3Bar(opt){
        //全局设置时间为中文
        var zh = d3.timeFormatDefaultLocale({
            decimal: ".",
            thousands: ",",
            grouping: [3],
            currency: ["¥", ""],
            dateTime: "%a %b %e %X %Y",
            date: "%Y/%-m/%-d",
            time: "%H:%M:%S",
            periods: ["上午", "下午"],
            days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
            shortDays: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
            months: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
            shortMonths: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
        });

        //设置时间格式
        var formatMillisecond = d3.timeFormat(".%L"),
            formatSecond = d3.timeFormat(":%S"),
            formatMinute = d3.timeFormat("%H:%M"),
            formatHour = d3.timeFormat("%H:00"),
            formatDay = d3.timeFormat("%B%d"),
            formatWeek = d3.timeFormat("%B%d"),
            formatMonth = d3.timeFormat("%B"),
            formatYear = d3.timeFormat("%Y");

        //格式化标准时间
        function multiFormat(date) {
            return (d3.timeSecond(date) < date ? formatMillisecond
                : d3.timeMinute(date) < date ? formatSecond
                    : d3.timeHour(date) < date ? formatMinute
                        : d3.timeDay(date) < date ? formatHour
                            : d3.timeMonth(date) < date ? (d3.timeWeek(date) < date ? formatDay : formatWeek)
                                : d3.timeYear(date) < date ? formatMonth
                                    : formatYear)(date);
        }

        //svg宽，高
        var container = document.querySelector(opt.selector),
            margin = {top: 15, right: 50, bottom: 15, left:400},
            width = container.offsetWidth - margin.left - margin.right,
            height = 158 - margin.top - margin.bottom,//container.offsetHeight,
            brushPos = {};

        //设置zoom缩放范围
        var startTime = new Date(opt.starttime),
            endTime = new Date(opt.endtime),

            minScaleTime = new Date(opt.mintime),
            maxScaleTime = opt.maxtime ? new Date(opt.maxtime) : Infinity,

            minTickLen = opt.mintick ? opt.mintick : 60 * 60 * 1000,
            maxTickLen = opt.maxtick ? opt.maxtick : 7 * 24 * 60 * 60 * 1000;

        //x值域
        const dateArray = d3.timeDays(startTime, endTime)

        //定义缩放函数
        var zoom = d3.zoom()
            .on('zoom', zoomed)
            .on("start", zoomStart)
            .on("end", zoomEnd);

        //定义画布大小
        var svg = d3.select(opt.selector).append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .attr('id', 'time-axis-svg')
            .attr('class', 'zoom')
            .attr("transform","translate(" + margin.left + "," + margin.top + ")")
            .call(zoom)

        // x轴比例尺
        var timeScale = d3.scaleTime()
            .domain([startTime, endTime])
            .range([0, width])
            .clamp(true)

        // 定义直方图数据
        var bins = createHistogram(opt.jsonData,dateArray)

        // 直方图容器g
        var hist = svg.append('g')
            .attr('class', 'histogram')

        // console.log(bins)
        // y轴比例尺
        const histHeight = 130
        var scaleLinear = d3.scaleLinear()
            .domain([0, d3.max(bins, d => d.length)])
            .range([0, histHeight])

        svg.append("g")
            .attr("class", "axis y")
            .call(scaleLinear);

        var axis = d3.axisBottom(timeScale)
            .tickSize(-height)
            .tickFormat(function (date) {
                return multiFormat(date);
            }).tickPadding(-10);

        var timeAxis = svg.append("g")
            .attr("class", "axis x")
            .attr("transform", "translate(0, " + (height) + ")")
            .call(axis);

        //brush
        var brush = d3.brushX()
            .extent([[0, 0], [width, height]])
            .on('brush', brushing)
            .on("end", brushend);

        var timeBrush = svg.append('g')
            .attr('class', 'brush')
            .call(brush);

        //添加图标
        d3.select('.inthemiddle').append('use').attr('href', '#mid').attr('fill', '#34ffeb');

        //brush自适应
        var brushMid = svg.append('g')
            .attr('class', 'inthemiddle')
            .attr('transform', `translate(${width - 26}, 8)`)
            .append('rect').attr('width', 18)
            .attr('height', 18).attr('fill', 'transparent').attr('cursor', 'pointer');

        brushMid.on('click', function () {
            if (d3.brushSelection(timeBrush.node()) || isSelectionRemove) {
                var selectionTimeMid = (Date.parse(brushPos.start) + Date.parse(brushPos.end)) / 2;
                var timeAxisDomainMid = (Date.parse(NewScale.domain()[0]) + Date.parse(NewScale.domain()[1])) / 2;
                var timeCha = timeAxisDomainMid - selectionTimeMid;
                if (Math.abs(timeCha) < 1000) return;

                NewScale.domain([Date.parse(NewScale.domain()[0]) - timeCha, Date.parse(NewScale.domain()[1]) - timeCha]);
                marginLimit();
                zoomStart();
                timeAxis.call(axis.scale(NewScale));
                selectionFollow();
                setAxisStyle();
                zoomEnd();
            }
        });

        //取消zoom双击放大
        svg.on('dblclick.zoom', null);

        //选区hover效果
        var formatTime = d3.timeFormat("%Y-%b-%d %H:%M:%S");
        var formatTime2 = d3.timeFormat("%H:%M:%S");
        var handle = timeBrush.selectAll('.handle').nodes();
        var tips = svg.append('g').attr('class', 'tips').attr('font-size', 12)
            .selectAll('tip').data(['left', 'right', 'center']).enter()
            .append('text').attr('class', function (d) { return d; }).attr('fill', '#fff');

        timeBrush.select('.selection').on('mouseover', function () {
            var time = `${formatTime(brushPos.start)} 到 ${formatTime(brushPos.end)}`;
            svg.select('.tips').attr('text-anchor', "middle");
            tips.filter('.center').text(time)
                .attr('x', function () {
                    var center = (d3.brushSelection(timeBrush.node())[0] + d3.brushSelection(timeBrush.node())[1]) / 2;
                    var left = center - this.getBBox().width / 2;
                    var right = center + this.getBBox().width / 2;
                    if (left < 0) {
                        return center - left + 6;
                    } else if (right > width) {
                        return center - right + width - 6;
                    } else {
                        return center;
                    }
                })
                .attr('y', 20);

        });

        timeBrush.select('.selection').on('mouseout', function () {
            tips.filter('.center').text('');
            svg.select('.tips').attr('text-anchor', "start");
        });

        function brushend() {
            var brushSelection = d3.brushSelection(timeBrush.node());
            if (!brushSelection) {
                zoomStart();
                var start = NewScale(Date.parse(brushPos.start));
                var end = NewScale(Date.parse(brushPos.end));
                var a = scaleLinear(start);
                var b = scaleLinear(end);
                brush.move(timeBrush, [a, b]);
                zoomEnd();
                return;
            }
            var isSameStart = Date.parse(brushPos.start) === Date.parse(NewScale.invert(brushSelection[0]));
            var isSameEnd = Date.parse(brushPos.end) === Date.parse(NewScale.invert(brushSelection[1]));
            if (isSameStart && isSameEnd) return;
            brushPos.start = NewScale ? NewScale.invert(brushSelection[0]) : timeScale.invert(brushSelection[0]);
            brushPos.end = NewScale ? NewScale.invert(brushSelection[1]) : timeScale.invert(brushSelection[1]);
            var transTimeStart = Math.floor(Date.parse(brushPos.start) / 1000); //精确到秒
            var transTimeEnd = Math.floor(Date.parse(brushPos.end) / 1000);
            if (typeof callback === 'function') callback(transTimeStart, transTimeEnd);
            if (typeof self.brushEnd === 'function') self.brushEnd(brushPos.start, brushPos.end);
            tips.text('');
        }

        function brushing() {
            //写入tip时间
            tips.filter(function (d, i) {
                return i < 2;
            }).attr('x', function (d, i) {
                return i === 0 ? handle[1].getBBox().x + 6 : handle[0].getBBox().x - this.getBBox().width;
            }).attr('y', function (d, i) {
                return i === 0 ? 20 : height - 20;
            }).text(function (d, i) {
                if (d3.brushSelection(timeBrush.node())) {
                    var ticks = NewScale.ticks();
                    if (Date.parse(ticks[1]) - Date.parse(ticks[0]) === 24 * 60 * 60 * 1000) {
                        return formatTime2(NewScale.invert(d3.event.selection[i]));
                    } else return formatTime(NewScale.invert(d3.event.selection[i]));
                }
            }).each(function (d, i) {
                var BBox = this.getBBox();
                var cha = BBox.x + BBox.width - width;
                if (cha > 0) d3.select(this).attr('x', BBox.x - cha - 6);
                else if (BBox.x <= 0) d3.select(this).attr('x', 6);
            });
            if (typeof self.brushing === 'function') {
                if (d3.brushSelection(timeBrush.node())) {
                    self.brushing(NewScale.invert(d3.event.selection[0]), NewScale.invert(d3.event.selection[1]));
                }
            }
        }

        function zoomStart() {
            brush.on('end', null);
            brush.on('brush', null);
        }

        // createButton()
        createButton()
        function createButton(){
            var ticks = _.cloneDeep(bins)
            console.log(ticks)

            var plusButton = svg.append("g")
                .attr("class","zoomButton plus")
                .attr("transform","translate(" + width + ",0)")
                // .classed("active", ticks.got.indexOf(ticks.cur)<(ticks.got.length-1))
                // .classed("inactive", ticks.got.indexOf(ticks.cur)==(ticks.got.length-1))
                .on("click",zoomed)

            plusButton.append("rect")
                .attr("width", 20)
                .attr("height", 20)

            plusButton.append("text")
                .attr("x", 10)
                .attr("y", 20)
                .text("+")
                .attr("text-anchor", "middle")

            var minusButton = svg.append("g")
                .attr("class","zoomButton minus")
                .attr("transform","translate(" + width + "," + 22+ ")")
                // .classed("active", ticks.got.indexOf(ticks.cur)>0)
                // .classed("inactive", ticks.got.indexOf(ticks.cur)==0)
                .on("click", zoomed)

            minusButton.append("rect")
                .attr("width", 20)
                .attr("height", 20)

            minusButton.append("text")
                .attr("x", 10)
                .attr("y", 20)
                .attr("dy", -2)
                .text("-")
                .attr("text-anchor", "middle");
        }

        //zoom进行时处理函数
        var NewScale = timeScale;
        var isSelectionRemove = false;
        function zoomed() {
            var xtimer = []
            timeAxis.selectAll('.tick').each(function (d, i) {
                xtimer.push(d)
            });
            console.log(xtimer[1]-xtimer[0])

            console.log('周', 7*24*60*60*1000)
            console.log('3天', 3*24*60*60*1000)
            console.log('天', 24*60*60*1000)
            console.log('12小时', 12*60*60*1000)
            console.log('6小时', 6*60*60*1000)
            console.log('2小时', 2*60*60*1000)
            console.log('1小时', 60*60*1000)


            zoom.scaleExtent([0, Infinity]);//恢复缩放最小化限制
            var newScale = d3.event.transform.rescaleX(timeScale).nice();

            NewScale = newScale;

            marginLimit();

            var leftLimit = newScale(Date.parse(minScaleTime)) > 0;
            var rightLimit = maxScaleTime === Infinity ? false : newScale(Date.parse(maxScaleTime)) < width;

            if (leftLimit || rightLimit) {
                console.log('已达到缩放最小化极限');
                newScale.domain([minScaleTime, maxScaleTime]);
                zoom.scaleExtent([d3.event.transform.k, Infinity]);//缩放最小化限制
            }

            //设置缩放最小刻度极限
            var ticks = newScale.ticks();
            if (Date.parse(ticks[1]) - Date.parse(ticks[0]) === minTickLen && ticks.length < 12) { //默认1分钟
                console.log('已达到最小刻度');
                zoom.scaleExtent([0, d3.event.transform.k]);
            }

            //设置缩放最大刻度极限
            if (Date.parse(ticks[1]) - Date.parse(ticks[0]) === maxTickLen && ticks.length < 10) { //默认一天
                console.log('已达到最大刻度');
                zoom.scaleExtent([d3.event.transform.k, Infinity]);
            }

            timeAxis.call(axis.scale(newScale));

            selectionFollow();

            setAxisStyle();
        }

        //设置缩放边缘极限
        function marginLimit() {

            var leftLimit = NewScale(Date.parse(minScaleTime)) > 0;
            var rightLimit = maxScaleTime === Infinity ? false : NewScale(Date.parse(maxScaleTime)) < width;

            if (leftLimit) {
                var cha = Date.parse(minScaleTime) - Date.parse(NewScale.domain()[0]);
                var newDomain = NewScale.domain().map(function (d) {
                    return Date.parse(d) + cha;
                });
                //console.log('已到达左边缘极限');
                NewScale.domain(newDomain);
            }

            if (rightLimit) {
                var cha = Date.parse(NewScale.domain()[1]) - Date.parse(maxScaleTime);
                var newDomain = NewScale.domain().map(function (d) {
                    return Date.parse(d) - cha;
                });
                //console.log('已到达右边缘极限');
                NewScale.domain(newDomain);
            }
        }

        /**
         *
         * @param data 外部的opt.jsonData数据
         * @param dateArray 横坐标值域
         * @returns {转化为d3直方图所需的数据格式}
         */
        function createHistogram(data,dateArray){

            // 直方图生成器
            var histogram = d3.histogram()  // histogram 将离散样本分成连续的无重叠的间隔
                .value(d => d.date)             // histogram.value - 为每个样本指定一个值访问器
                .domain(timeScale.domain())             // histogram.domain - 指定可观测值的间隔
                .thresholds(dateArray) // histogram.thresholds - 指定值划分成不同箱的方法

            var result = histogram(data)
            return result

        }

        function zoomEnd() {

            var xtimer = []
            timeAxis.selectAll('.tick').each(function (d, i) {
                xtimer.push(d)
            });
            var test = createHistogram(opt.jsonData, xtimer)
            drawHistogram(test)
            console.log("=======重绘直方图")

            brush.on('end', brushend);
            brush.on('brush', brushing);

        }

        setAxisStyle();
        function setAxisStyle() {

            drawHistogram(bins)

            timeAxis.selectAll('.tick').select('text').attr('fill', '#fff');

        }

        function drawHistogram(bins) {
            scaleLinear.domain([0, d3.max(bins, d => d.length)])
                .range([0, histHeight])

            hist.selectAll('.hisBar').remove()

            var bar = hist.selectAll('.bar')
                .data(bins)
                .enter()
                .append('g')
                .attr('transform', function(d){
                    return `translate(${timeScale(d.x0)}, ${histHeight-scaleLinear(d.length)})`
                })
                .attr('class', 'hisBar')

            bar.append('rect')
                .attr('class', 'bar')
                .attr('width', function(d){
                    return width/bins.length
                })
                .attr('height', function (d) {
                    return scaleLinear(d.length)
                })
                .attr('fill', "#4D81C6")

            bar.append('text')
                .attr('dy', '.75em')
                .attr('y', '6')
                .attr('x', d => (timeScale(d.x1) - timeScale(d.x0)) / 2)
                .attr('text-anchor', 'middle')
                .text(d => d.length)
                .attr('fill', 'white')
        }

        //设置brush跟随缩放、resize移动
        function selectionFollow() {
            if (d3.keys(brushPos).length && d3.brushSelection(timeBrush.node()) || isSelectionRemove) {

                var start = NewScale(Date.parse(brushPos.start));
                var end = NewScale(Date.parse(brushPos.end));
                var a = scaleLinear(start);
                var b = scaleLinear(end);

                //在left边缘消失
                if (start <= a && end <= a) {
                    isSelectionRemove = true;
                } else if (start >= b && end >= b) { //在right边缘消失
                    isSelectionRemove = true;
                } else {
                    isSelectionRemove = false;
                }
                brush.move(timeBrush, [a, b]);
            }
        }

        var self = this;
        this.timeParameter = function () {
            return {
                startTime: brushPos.start,
                endTime: brushPos.end,
                mintime: opt.mintime,
                maxtime: opt.maxtime
            }
        };

        this.resize = function () {
            width = container.offsetWidth;
            height = container.offsetHeight;
            zoomStart();
            svg.attr("width", width).attr("height", height);
            timeBrush.call(brush.extent([[0, 0], [width, height]]));
            timeAxis.call(axis.scale(NewScale.range([0, width])));
            svg.select('.inthemiddle').attr('transform', `translate(${width - 26}, 8)`);
            selectionFollow();
            zoomEnd();
        };

        this.setSelectionTimeRange = function (start, end) {
            var startTime = Date.parse(start);
            var endTime = Date.parse(end);
            if (startTime < endTime) {
                brush.move(timeBrush, [scaleLinear(NewScale(startTime)), scaleLinear(NewScale(endTime))]);
            } else {
                console.log('时间区间无效');
            }
        };

        var layer_Group;
        this.brushEnd = function (start, end) {
            d3.json('lib/d3/earthquakes.geojson', function (err, data) {
                var featuresData = data.features
                layerGroup = L.layerGroup()
                featuresData.forEach(function (item, index) {
                    if (new Date(item.properties.time) > start && new Date(item.properties.time) < end) {
                        var circlemarker = L.circleMarker(item.geometry.coordinates, {
                            radius: pointRadius(item),
                            fillColor: pointColor(item),
                            fillOpacity: 0.7,
                            weight: 0.5,
                            color: '#fff'
                        })
                        layerGroup.addLayer(circlemarker)
                    }

                    if (layer_Group && index === 0) {
                        mymap.removeLayer(layer_Group)
                    }
                    if (featuresData.length - 1 === index) {
                        layer_Group = layerGroup.addTo(mymap)
                    }
                })
            });

            function pointColor(feature) {
                return feature.properties.mag > 5 ? '#f55' : '#a00';
            }

            function pointRadius(feature) {
                return (feature.properties.mag - 4) * 10;
            }

        };
        this.brushing = function (start, end) { };
        this.brushMove = function (start, end) {
            var startTime = Date.parse(start);
            var endTime = Date.parse(end);
            console.log();
            if (startTime < endTime) {
                brush.move(timeBrush, [scaleLinear(NewScale(startTime)), scaleLinear(NewScale(endTime))]);
            } else {
                console.log('时间区间无效');
            }
        };
        this.updateAxis = function (start, end) {
            var startTime = Date.parse(start);
            var endTime = Date.parse(end);
            if (startTime < endTime) {
                zoomStart();
                NewScale.domain([startTime, endTime]);
                marginLimit();
                if (d3.brushSelection(timeBrush.node())) brush.move(timeBrush, [0, 0]);
                timeAxis.call(axis.scale(NewScale));
                setAxisStyle();
                zoomEnd();
            } else {
                console.log('时间区间无效');
            }

        };

        var reBrushStart = 0;
        document.addEventListener('mousedown', function () {
            console.log("开始")
            svg.on('mouseenter', function () {
                if (d3.brushSelection(timeBrush.node())) {
                    brush.move(timeBrush, [0, 0]);
                }
                if (!reBrushStart) {
                    reBrushStart = scaleLinear(d3.event.offsetX - parseInt(svg.style('padding-left')));
                }
            });
            svg.on('mousemove', function () {
                if (!reBrushStart) return;

                brush.on('end', null);
                var reBrushEnd = scaleLinear(d3.event.offsetX - parseInt(svg.style('padding-left')));
                if (reBrushStart > reBrushEnd) {
                    brush.move(timeBrush, [reBrushEnd, reBrushStart]);
                } else {
                    brush.move(timeBrush, [reBrushStart, reBrushEnd]);
                }
                brush.on('end', brushend);
                console.log("结束")
            });
        });

        document.addEventListener('mouseup', function () {
            svg.on('mousemove', null);
            svg.on('mouseenter', null);
            reBrushStart = 0;
            brushend();
        });
    }

//border: 1px solid #ddd;
// position: absolute;
// left: 0px;
//     //background-color: #D9D9D9;
//     .tick line{
//     opacity: 0;
// }

// text {
//     font - family: 'Play', sans - serif;
//     pointer - events: none;
// }

//     .axis.x path{
//     opacity: 0;
// }
//     .zoomButton {
//     font - size: 33px;
//     fill: white;
// }

//     .zoomButton.plus rect {
//     fill: #5cb85c;
// }

//     .zoomButton.minus rect {
//     fill: #d9534f;
// }

//     .active {
//     opacity: 1;
//     transition: opacity 1000ms;
// }

//     .inactive {
//     opacity: .1;
//     transition: opacity 1000ms;
// }
    //.axis path{
    //  opacity: 0;
    //}
    //.ui-brush {
    //  background:#f8f8f8;
    //  /*position:absolute;*/
    //  /*bottom:0;right:0;left:0;*/
    //  height:100px;
    //}
    //.brush .extent {
    //  stroke:#fff;
    //  fill-opacity:0.125;
    //  shape-rendering:crispEdges;
    //}


// index
// function createButton() {
//     var plusButton = svg.append("g")
//         .attr("class", "zoomButton plus")
//         .attr("transform", "translate(" + (width - 20) + ",0)")
//         // .classed("active", ticks.got.indexOf(ticks.cur)<(ticks.got.length-1))
//         // .classed("inactive", ticks.got.indexOf(ticks.cur)==(ticks.got.length-1))
//         .on("click", zoomed)

//     plusButton.append("rect")
//         .attr("width", 20)
//         .attr("height", 20)

//     plusButton.append("text")
//         .attr("x", 10)
//         .attr("y", 20)
//         .text("+")
//         .attr("text-anchor", "middle")

//     var minusButton = svg.append("g")
//         .attr("class", "zoomButton minus")
//         .attr("transform", "translate(" + (width - 40) + ",0)")
//         // .classed("active", ticks.got.indexOf(ticks.cur)>0)
//         // .classed("inactive", ticks.got.indexOf(ticks.cur)==0)
//         .on("click", zoomed)

//     minusButton.append("rect")
//         .attr("width", 20)
//         .attr("height", 20)

//     minusButton.append("text")
//         .attr("x", 10)
//         .attr("y", 20)
//         .attr("dy", -2)
//         .text("-")
//         .attr("text-anchor", "middle");
// }
